﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.LIB;
using YJKRevitFamilyDataBase;
using YJKExcelFormTool.Creator;
using YJKExcelFormTool.DataDefine;
using YJKExcelFormTool.Forms;
using YJKExcelFormTool.Kits;

namespace YJKExcelFormTool.Designer
{
	internal class MaterialTableDesigner
	{
		public MaterialTableDesigner(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
		}

		public Result Setting(ref string message, SubjectType subjectType, MaterialProgramInfos._Tag_TemplateType templateType, string programId)
		{
			string defaultSettingFileName = this.GetDefaultSettingFileName(subjectType);
			using (MaterialTableForm materialTableForm = new MaterialTableForm(this.m_Revit, defaultSettingFileName, templateType, subjectType, programId))
			{
				if (materialTableForm.ShowDialog() != DialogResult.OK)
				{
					return Autodesk.Revit.UI.Result.Cancelled;
				}
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public Result Drawing(string programId, ImportMaterialTableInfos importTableInfos, ref string message)
		{
			this.m_ImportTableInfos = importTableInfos;
			if (new ViewControler(this.m_Revit, ViewControler.TableViewType.TVT_MATERIALTABLE).CreateDraftingView(100) == ViewSelectResult.VSR_Cancel)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			if (!this.FindedDefaultSettingFile(this.m_ImportTableInfos.ImportSubjectType, ref message))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			TableInfos tableInfos = this.CreateTableInfos(this.m_ImportTableInfos.ImportSubjectType, programId);
			TableDrawingToRevitKit tableDrawingToRevitKit = new TableDrawingToRevitKit(this.m_Revit, tableInfos, null);
			try
			{
				tableDrawingToRevitKit.Drawing(true);
			}
			catch
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public Result Export(string programId, ImportMaterialTableInfos importTableInfos, ref string message)
		{
			this.m_ImportTableInfos = importTableInfos;
			if (!this.FindedDefaultSettingFile(this.m_ImportTableInfos.ImportSubjectType, ref message))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			TableInfos tableInfos = this.CreateTableInfos(this.m_ImportTableInfos.ImportSubjectType, programId);
			switch (this.m_ImportTableInfos.ImportSubjectType)
			{
			default:
			{
				string name = tableInfos.Head.TableSourceInfo.Name;
				if (!File.Exists(name))
				{
					int num = name.LastIndexOf("\\");
					string fileName = name.Substring(num + 1, name.Length - (num + 1));
					tableInfos.Head.TableSourceInfo.Name = this.GetDefaultTemplateFile(fileName);
				}
				TableExportKit tableExportKit = new TableExportKit(tableInfos, true, default(TableExportKit.FontSetting));
				Transaction transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document);
				transaction.Start("Export table");
				try
				{
					tableExportKit.ExportToExcel();
					transaction.Commit();
				}
				catch
				{
					if (transaction != null)
					{
						transaction.RollBack();
					}
					return Autodesk.Revit.UI.Result.Failed;
				}
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			}
		}

		private string GetDefaultTemplateFile(string fileName)
		{
			string text;
			if (this.m_ImportTableInfos.ImportSubjectType == SubjectType.Electric)
			{
				text = Product.WorkingLocation + "Electrical_" + fileName;
			}
			else if (this.m_ImportTableInfos.ImportSubjectType == SubjectType.HVAC)
			{
				text = Product.WorkingLocation + "HVAC_" + fileName;
			}
			else
			{
				text = Product.WorkingLocation + "Plumbing_" + fileName;
			}
			if (!File.Exists(text))
			{
				string sourceFileName;
				if (this.m_ImportTableInfos.ImportSubjectType == SubjectType.Electric)
				{
					sourceFileName = AssistFunc.GetAppRootPath() + "\\Data\\ElectricalData\\" + fileName;
				}
				else if (this.m_ImportTableInfos.ImportSubjectType == SubjectType.HVAC)
				{
					sourceFileName = AssistFunc.GetAppRootPath() + "\\Data\\HVACData\\" + fileName;
				}
				else
				{
					sourceFileName = AssistFunc.GetAppRootPath() + "\\Data\\PlumbingData\\" + fileName;
				}
				this.CopyFile(sourceFileName, text);
			}
			return text;
		}

		private void CopyFile(string sourceFileName, string destFileName)
		{
			try
			{
				File.Copy(sourceFileName, destFileName);
			}
			catch (Exception)
			{
			}
		}

		public bool GetStatisticsDetailsWithMaterialTable(SubjectType subjectType, ExternalCommandData cmdData, string programId, ref List<string> selectedCategoryNameList, ref List<CombinationOfAttributes> combinationOfAttributesList, ref List<MaterialProgramInfos.FilterType> filterTypeList, ref string message)
		{
			string defaultSettingFileName = this.GetDefaultSettingFileName(subjectType);
			return new MaterialTableCreater(cmdData).GetStatisticsDetailsWithMaterialTable(defaultSettingFileName, programId, ref selectedCategoryNameList, ref combinationOfAttributesList, ref filterTypeList, ref message);
		}

		public List<MaterialProgramInfos.BasicInfo> GetProgramInfoList(SubjectType subjectType, bool isExcelTemplate)
		{
			string defaultSettingFileName = this.GetDefaultSettingFileName(subjectType);
			return new TableCreator().GetProgramInfoList(defaultSettingFileName, isExcelTemplate);
		}

		public void RemoveProgram(SubjectType subjectType, string programId)
		{
			string defaultSettingFileName = this.GetDefaultSettingFileName(subjectType);
			new TableCreator().RemoveProgram(defaultSettingFileName, programId);
		}

		private TableInfos CreateTableInfos(SubjectType subjectType, string programId)
		{
			string defaultSettingFileName = this.GetDefaultSettingFileName(subjectType);
			MaterialTableCreater materialTableCreater = new MaterialTableCreater(this.m_Revit);
			MaterialProgramInfos materialProgramInfos = new MaterialProgramInfos();
			materialTableCreater.ReadTableSetting(defaultSettingFileName, programId, ref materialProgramInfos);
			TableInfos tableInfos = materialProgramInfos.TableInfos;
			tableInfos.Body = materialTableCreater.CreateTableBody(tableInfos.EffectiveColumnParameterList(), this.m_ImportTableInfos);
			return tableInfos;
		}

		[DllImport("kernel32.dll")]
		public static extern IntPtr _lopen(string lpPathName, int iReadWrite);

		[DllImport("kernel32.dll")]
		public static extern bool CloseHandle(IntPtr hObject);

		private bool ValidatingTableFile(string vFileName, ref string message)
		{
			if (!File.Exists(vFileName))
			{
				message = "文件都不存在";
				return false;
			}
			IntPtr intPtr = MaterialTableDesigner._lopen(vFileName, 66);
			if (intPtr == this.HFILE_ERROR)
			{
				message = "文件被占用！";
				return false;
			}
			MaterialTableDesigner.CloseHandle(intPtr);
			return true;
		}

		private string GetDefaultSettingFileName(SubjectType subjectType)
		{
			string text;
			if (subjectType == SubjectType.Electric)
			{
				text = Product.WorkingLocation + "ElectricMaterialTableSetting.xml";
			}
			else if (subjectType == SubjectType.HVAC)
			{
				text = Product.WorkingLocation + "HVACMaterialTableSetting.xml";
			}
			else
			{
				text = Product.WorkingLocation + "PlumbingMaterialTableSetting.xml";
			}
			if (!File.Exists(text))
			{
				string sourceFileName;
				if (subjectType == SubjectType.Electric)
				{
					sourceFileName = AssistFunc.GetAppRootPath() + "\\Data\\ElectricalData\\ElectricMaterialTableSetting.xml";
				}
				else if (subjectType == SubjectType.HVAC)
				{
					sourceFileName = AssistFunc.GetAppRootPath() + "\\Data\\HVACData\\HVACMaterialTableSetting.xml";
				}
				else
				{
					sourceFileName = AssistFunc.GetAppRootPath() + "\\Data\\PlumbingData\\PlumbingMaterialTableSetting.xml";
				}
				this.CopyFile(sourceFileName, text);
			}
			return text;
		}

		private string GetSubjectName(SubjectType subjectType)
		{
			string result;
			if (subjectType == SubjectType.Electric)
			{
				result = "电气";
			}
			else if (subjectType == SubjectType.HVAC)
			{
				result = "暖通";
			}
			else
			{
				result = "给排水";
			}
			return result;
		}

		private bool FindedDefaultSettingFile(SubjectType subjectType, ref string message)
		{
			string defaultSettingFileName = this.GetDefaultSettingFileName(subjectType);
			string subjectName = this.GetSubjectName(subjectType);
			if (!this.ValidatingTableFile(defaultSettingFileName, ref message))
			{
				message = subjectName + "专业未进行材料表表头设置，请先完成相应设置。";
				return false;
			}
			return true;
		}

		private ExternalCommandData m_Revit;

		private ImportMaterialTableInfos m_ImportTableInfos;

		public const int OF_READWRITE = 2;

		public const int OF_SHARE_DENY_NONE = 64;

		public readonly IntPtr HFILE_ERROR = new IntPtr(-1);
	}
}
